#ifndef STUDENT_H
#define STUDENT_H

#include "Course.h"

class Student
{
public:
  Student(const std::string& _name)
    : name(_name), my_courses(new Courses)
  { }

  const std::string&
  getName() const
  {
    return name;
  }
  
  const CoursesPtr&
  getCourses() const
  {
    return my_courses;
  }

  void
  add_course(Courses::const_iterator beg,
	     Courses::const_iterator end,
	     std::back_insert_iterator<Courses> c,
	     const std::string& _course_name);

private:
  std::string name;
  CoursesPtr my_courses;
};



typedef boost::shared_ptr<Student> StudentPtr;
typedef std::vector<StudentPtr> Students;
typedef boost::shared_ptr<Students> StudentsPtr;


void
Student::add_course(Courses::const_iterator beg, 
		    Courses::const_iterator end,
		    std::back_insert_iterator<Courses> c,
		    const std::string& _course_name)
{
  Courses::const_iterator it = find_if(beg, end, CompareCourses(_course_name));
  if (it != end)
    {
      my_courses->push_back(*it);
    }
  else
    {  
      CoursePtr new_course(new Course(_course_name));
      c = new_course;
      my_courses->push_back(new_course);
    }
}


std::ostream&
operator<< (std::ostream& os, const Student& s)
{
  os << s.getName();
  os << std::endl << "{" << std::endl;
  os << s.getCourses();
  os << std::endl << "}" << std::endl;

  return os;
}


std::ostream&
operator<< (std::ostream& os, const StudentPtr& sp)
{
  os << *sp;
  return os;
}


std::ostream&
operator<< (std::ostream& os, const StudentsPtr& sp)
{
  std::copy(sp->begin(), sp->end(), std::ostream_iterator<StudentPtr> (os, "\n"));
  return os;
}

#endif

// Local Variables:
// mode: C++
// End:
